namespace KinonekoSoftware.Foundation.Bus
{
    public class MessageBus<TMSG> : IMessageBus<TMSG> where TMSG : IMessage
    {
        public MessageBus()
        {
            InterestHandlers = new Dictionary<Type, MessageHandler<TMSG>>();
        }
        
        public MessageBus(MessageHandler<TMSG> handler)
        {
            InterestHandlers = new Dictionary<Type, MessageHandler<TMSG>>();
            FallbackHandler  = handler;
        }

        public void Interest<T>(MessageHandler<TMSG> handler) where T : IMessage
        {
            if (handler is null)
            {
                return;
            }

            var type = typeof(T);
            InterestHandlers[type] = handler;
        }

        public void OnNext(TMSG msg)
        {
            if (msg is null)
            {
                return;
            }


            var type = msg.OverrideMappingBehavior ? msg.OverrideMapping : msg.GetType();

            if (InterestHandlers.Count > 0 && InterestHandlers.TryGetValue(type, out var handler))
            {
                handler(msg);
                return;
            }
            
            FallbackHandler?.Invoke(msg);
        }
        
        public IDictionary<Type, MessageHandler<TMSG>> InterestHandlers { get; }
        public MessageHandler<TMSG>                    FallbackHandler  { get; set; }
    }
}